package org.xhy.security.provider;

import org.springframework.security.authentication.AccountStatusUserDetailsChecker;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsChecker;
import org.springframework.util.Assert;
import org.xhy.security.service.MyUserDetailService;
import org.xhy.security.token.SmsAuthenticationToken;

import java.util.Collection;

public class SmsAuthenticationProvider implements AuthenticationProvider {

    private UserDetailsChecker preAuthenticationChecks = new AccountStatusUserDetailsChecker();

    private MyUserDetailService myUserDetailService;

    public void setMyUserDetailService(MyUserDetailService myUserDetailService) {
        this.myUserDetailService = myUserDetailService;
    }

    //authentication就是filter传过来的token
    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
        Assert.isTrue(supports(authentication.getClass()),"类型不匹配！");

        //authentication强转为SmsAuthenticationToken
        SmsAuthenticationToken smsAuthenticationToken = (SmsAuthenticationToken) authentication;

        //取出phone
        String phone = (String) smsAuthenticationToken.getPrincipal();

        //MyUserDetailService把手机号当用户民去查询
        UserDetails userDetails = myUserDetailService.loadUserByUsername(phone);
        Assert.notNull(userDetails,"手机号不存在！");

        //检查账号
        this.preAuthenticationChecks.check(userDetails);

        //认证成功后的对象
        return createSuccessAuthentication(userDetails.getUsername(),authentication,userDetails);
    }

    protected Authentication createSuccessAuthentication(Object principal, Authentication authentication, UserDetails user) {

        //处理权限
        Collection<GrantedAuthority> authorities = (Collection<GrantedAuthority>) user.getAuthorities();

        //封装结果
        SmsAuthenticationToken result =
                new SmsAuthenticationToken((String)principal,authorities);

        result.setDetails(authentication.getDetails());

        return result;
    }

    //是否支持
    public boolean supports(Class<?> authentication) {
        return SmsAuthenticationToken.class.isAssignableFrom(authentication);
    }
}
